
package andre.grids.filesystem.server.filemanagement;

import andre.grids.db.DbLogEntryQueries;
import andre.grids.db.DbReplicaQueries;
import andre.grids.db.dataclasses.DbLogEntry;
import andre.grids.db.dataclasses.DbPeer;
import andre.grids.filesystem.common.FileOperations;
import andre.grids.filesystem.common.ReadOperation;
import andre.grids.filesystem.common.WriteOperation;
import andre.grids.guids.IGuid;
import andre.grids.network.FileServerTable;
import andre.grids.network.PeerObjects;
import java.rmi.RemoteException;
import andre.grids.util.log.*;

/**
 *
 * @author andre
 * Esta classe foi criada para permitir aos DMServers apresentar uma
 * interface para o sistema de arquivos.
 * A decisão por não permitir aos clientes conversarem diretamente com
 * os servidores de arquivos foi tomada por questões de segurança e
 * isolamento da infra-estrutura.
 * Ideia dada pelo professor de S.D. - Alexandre
 */
public class FileSystemOperationsProxy 
        implements FileOperations {

    public void createFile(IGuid fileGuid) throws RemoteException {
        throw new UnsupportedOperationException("Esta operação não pode ser chamada em um proxy!");
    }

    public void deleteFile(IGuid fileGuid) throws RemoteException {
        throw new UnsupportedOperationException("Esta operação não pode ser chamada em um proxy!");
    }

    public int lock(IGuid file, int lockType) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public ReadOperation read(IGuid file, long startPos, int count) throws RemoteException {
        DbReplicaQueries query = new DbReplicaQueries();
        DbPeer [] replicasHost = query.getReplicasByFileGuid(file);
        PeerObjects objs = FileServerTable.getInstance().getObjectsFor(replicasHost[0].getPeerName());
        return objs.getFile().read(file, startPos, count);
    }

    public int refreshLock(IGuid file, int lockType) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public WriteOperation write(IGuid file, long fileStart, byte[] buff) throws RemoteException {
        DbReplicaQueries query = new DbReplicaQueries();
        DbPeer [] replicasHost = query.getReplicasByFileGuid(file);
        PeerObjects objs[] = new PeerObjects[replicasHost.length];
        int x = 0;
        for(DbPeer p: replicasHost)
            objs[x++] = FileServerTable.getInstance().getObjectsFor(p.getPeerName());
        
        WriteOperation op = null;
        RemoteException lastError = null;
        
        for(PeerObjects pObj: objs) {
            try {
                op = pObj.getFile().write(file, fileStart, buff);
                if (op != null) {
                    Log.logUpdateFile(file.toHexString(), pObj.getHost(), fileStart, buff);
                }
            }
            catch(RemoteException e) {
                lastError = e;
            }
        }
        
        if (op == null && lastError != null)
            throw lastError;
        
        return op;
    }

    public DbLogEntry[] getLogSince(int year, int dayOfYear, int hour, int minute, int second) throws RemoteException {
        DbLogEntryQueries query = new DbLogEntryQueries();
        return query.getEntries(year, dayOfYear, hour, minute, second, false);
    }

    public FileOperations isAlive() throws RemoteException {
        return this;
    }
    
}
